﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FormattingConverter.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the <seealso cref="FormattingConverter" /> type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Client.Common.Converters
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Windows.Data;

    /// <summary>
    /// Defines the <seealso cref="FormattingConverter"/> type.
    /// </summary>
    public class FormattingConverter : IValueConverter
    {
        /// <summary>
        ///     Takes a number, date or string and formats the value according to the paramenter and culture
        /// </summary>
        /// <param name="value" type="Object">
        ///     <para>
        ///         Number, date or string
        ///     </para>
        /// </param>
        /// <param name="targetType" type="System.Type">
        ///     <para>
        ///         This is automatically passed in and is the type of the target (calling) UI Element.
        ///     </para>
        /// </param>
        /// <param name="parameter" type="Object">
        ///     <para>
        ///        A .Net formatting code.
        ///        Example, for currency pass the familar "{0:c}" like this : \{0:c\} or like this {}{0:c}
        ///        Both ways work.
        ///        You can also include a string like this, ' My Money \{0:c\}'
        ///        If you do not use the {}{0:c} syntax, then it is necessary to escape the "{" and "}" otherwise parser will get confused because "{" and "}" is used as delimiters in the Binding statement.
        ///        See the remarks below for an example of the Binding statement.
        ///     </para>
        /// </param>
        /// <param name="culture" type="System.Globalization.CultureInfo">
        ///     <para>
        ///         Not required to be passed in xaml code. WPF automatically passes the current culture info for you.
        ///     </para>
        /// </param>
        /// <returns>
        ///     The value, formatted according to the parameter.
        /// </returns>
        /// <remarks>
        /// Usage Examples:
        /// Text="{Binding Path=BirthDay, Converter={StaticResource FormattingConverter}, ConverterParameter=\{0:M\}, Mode=Default}"
        /// Text="{Binding Path=BirthDay, Converter={StaticResource FormattingConverter}, ConverterParameter=\{0:R\}, Mode=Default}"
        /// Text="{Binding Path=BirthDay, Converter={StaticResource FormattingConverter}, ConverterParameter='{}{0:ddd, d MMM yyyy} is my day!', Mode=Default}"
        /// </remarks>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (parameter != null)
            {
                string strFormatString = parameter.ToString();

                if (!string.IsNullOrEmpty(strFormatString))
                {
                    return string.Format(culture, strFormatString, value);
                }
            }

            return value.ToString();
        }

        /// <summary>
        /// Converts a value.
        /// </summary>
        /// <param name="value">The value that is produced by the binding target.</param>
        /// <param name="targetType">The type to convert to.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>
        /// A converted value. If the method returns null, the valid null value is used.
        /// </returns>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            TypeConverter objTypeConverter = System.ComponentModel.TypeDescriptor.GetConverter(targetType);
            object objReturnValue = null;

            if (objTypeConverter.CanConvertFrom(value.GetType()))
            {
                objReturnValue = objTypeConverter.ConvertFrom(value);
            }

            return objReturnValue;
        }
    }
}